package com.wl.boot.batch.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.wl.boot.batch.bean.entity.CommonExcelPageField;
import com.wl.boot.batch.service.impl.ExcelServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;

/**
 * @author wanglu
 */
public class ExcelListener extends AnalysisEventListener {

    private Logger logger = LoggerFactory.getLogger(ExcelListener.class);
    /**
     * 每隔3000条存储数据库，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 3000;

    private List<Object> datas = new ArrayList<>();
    private ExcelServiceImpl service;
    private List<CommonExcelPageField> fields = new ArrayList<>();
    private String tableName;
    private int startRow = 1;
    private int size = 0;

    public ExcelListener() {
    }

    public ExcelListener(ExcelServiceImpl service, List<CommonExcelPageField> epf, int startRow, String targerTable) {
        this.service = service;
        this.fields = epf;
        this.startRow = startRow;
        this.tableName = targerTable;
    }

    @Override
    public void invokeHead(Map headMap, AnalysisContext context) {
        this.size = headMap.size();
    }

    /**
     * 通过 AnalysisContext 对象还可以获取当前 sheet，当前行等数据
     * 存在当前行后几列为空时，Object返回的map长度不够的情况，直接在行尾缺位补null;
     */
    @Override
    public void invoke(Object object, AnalysisContext context) {
        if (context.getCurrentRowNum() + 1 < startRow) {
            return;
        }
        if (object instanceof LinkedHashMap && ((LinkedHashMap) object).size() != this.size) {
            IntStream.range(0, this.size - ((LinkedHashMap) object).size()).forEach(e -> {
                ((LinkedHashMap) object).put(((LinkedHashMap) object).size() + 1, null);
            });
            logger.info("当前行:" + (context.getCurrentRowNum() + 1) + "末尾补null完成");
        }
        if (datas.size() < BATCH_COUNT) {
            datas.add(object);
        } else {
//            doSomething();
            datas.clear();
        }
    }

    /**
     * 根据业务自行实现该方法
     */
    private void doSomething() {
        service.MybatisForeachBatch(datas, fields, tableName);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        if (datas.size() > 0) {
//            doSomething();
        }
        datas.clear();
    }

    public List<Object> getDatas() {
        return datas;
    }

    public void setDatas(List<Object> datas) {
        this.datas = datas;
    }
}
